﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ExecuteResult er;
            Efem efem = new Efem();
            efem.Connect("127.1", 13000);
            System.Threading.Thread.Sleep(100);


            List<string> l = new List<string> { "Equals", "ToString", "GetHashCode", "GetType", "GetCommandState", "Disconnect", "Connect" };
            var ms = (from m in typeof(Efem).GetMethods()
                      where !l.Contains(m.Name)
                      select m).ToList();
            Dictionary<string, System.Reflection.ParameterInfo[]> mp = new Dictionary<string, System.Reflection.ParameterInfo[]>();
            System.Reflection.ParameterInfo[] ps;

            int i = 0;
            string mi = string.Join("\r\n", from m in ms select $"[{i++}]{m}");
            string line;
            while (true)
            {
                Console.Clear();
                Console.WriteLine(mi);
                Console.WriteLine();
                Console.Write("\r选择要调用的方法：");

                line = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line == "q" || line == "Q")
                {
                    break;
                }
                if (!int.TryParse(line, out i) || i < 0 || i >= ms.Count)
                {
                    continue;
                }
                Console.WriteLine();
                var m = ms[i];
                if (mp.ContainsKey(m.Name))
                {
                    ps = mp[m.Name];
                }
                else
                {
                    ps = mp[m.Name] = m.GetParameters();
                }
                Console.WriteLine($"调用函数{i}：{m}");
                Console.WriteLine();
                if (ps.Length > 0)
                {
                    i = 0;
                    foreach (var p in ps)
                    {
                        Console.WriteLine($"[{i++}]:{p.ParameterType.Name}  {p.Name}");
                        if (p.ParameterType.IsEnum)
                        {
                            Console.WriteLine($"\t可选值有：{string.Join("、", Enum.GetNames(p.ParameterType))}");
                        }
                    }
                param:
                    Console.Write("\r请输入参数，用逗号分隔：");
                    line = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    var pl = line.Split(',', '，');
                    if (pl.Length != ps.Length)
                    {
                        goto param;
                    }
                    object[] arg = new object[ps.Length];
                    i = 0;
                    foreach (var p in ps)
                    {
                        arg[i] = TypeDescriptor.GetConverter(p.ParameterType).ConvertFromString(pl[i]);
                        i++;
                    }

                    er = m.Invoke(efem, arg) as ExecuteResult;
                }
                else
                {
                    er = m.Invoke(efem, null) as ExecuteResult;
                }
                new System.Threading.Thread(MonitorResult) { IsBackground = true }.Start(er);
                //while (er.State == CommandStatus.Executing) { }
                //Console.WriteLine(er.State);
                //Console.WriteLine(string.Join("\r\n", er.FullMessages));
                //Console.WriteLine(er.Result);


                Console.WriteLine("按任意键继续。。。");
                Console.ReadKey();
            }

            efem.Disconnect();


            Console.ReadKey();
        }

        static void MonitorResult(object obj)
        {
            var er = obj as ExecuteResult;
            while (er.State == CommandStatus.Executing) System.Threading.Thread.Sleep(5);
            Console.WriteLine(er.State);
            foreach (var l in er.FullMessages)
            {
                Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss.fffffff} : {1}", l.Timestamp, l.Message);
            }
            Console.WriteLine(er.Result);
        }
    }
}
